package com.javaprint.order.printer;


import com.javaprint.order.settings.PrintSettings;
import com.javaprint.order.settings.TmParameters;
import com.javaprint.order.util.BarcodeUtil;
import com.javaprint.order.util.XmlBuilder;
import com.javaprint.order.vo.PrintVo;
import me.javy.helper.Helper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import javax.print.*;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.print.*;
import java.awt.print.Paper;
import java.io.*;
import java.text.SimpleDateFormat;


/**
 *打印标签
 * @since 2020/3/26 11:17
 **/
public class PrintTmOrder implements Printable{


    private static final Logger logger = LoggerFactory.getLogger(PrintTmOrder.class);
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private static PrintTmOrder myPrint;
    private PrintVo printVo;
    private Integer totalPageCount;
    private static PrintSettings printSettings;
    @PostConstruct
    //通过@PostConstruct实现初始化bean之前进行的操作
    public void init() {
        myPrint = this;
    }
    static {
        try {
            //读取Resource目录下的XML文件
            Resource resource = new ClassPathResource("printSettings.xml");
            //利用输入流获取XML文件内容
            BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream(), "UTF-8"));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }
            br.close();
            //XML转为JAVA对象
            PrintSettings settings = (PrintSettings) XmlBuilder.xmlStrToObject(PrintSettings.class, buffer.toString());
            printSettings = settings;
        }catch (Exception e){
            logger.error("异常",e);
        }
    }

    public PrintTmOrder() {
    }

    public PrintTmOrder(PrintVo printVo) {
        this.printVo = printVo;
        logger.info("运单编号："+printVo.getOrderCode());
    }

    public Integer getTotalPageCount() {
        return totalPageCount;
    }

    public void setTotalPageCount(Integer totalPageCount) {
        this.totalPageCount = totalPageCount;
    }

    /**
     * 打印方法
     * graphics - 用来绘制页面的上下文，即打印的图形
     * pageFormat - 将绘制页面的大小和方向，即设置打印格式，如页面大小一点为计量单位（以1/72 英寸为单位，1英寸为25.4毫米。A4纸大致为595 × 842点）
     * pageIndex - 要绘制的页面从 0 开始的索引 ，即页号
     */
    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        logger.info("pageIndex为:" + pageIndex);
        //获取数据
        Graphics2D g2 = (Graphics2D) graphics;
        g2.setColor(Color.black);
        if (pageIndex > totalPageCount - 1) {
            return NO_SUCH_PAGE;
        } else {
            logger.info("开始打印第:" + (pageIndex + 1) + "页");
            g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());// 转换坐标，确定打印边界

            //打印起点坐标
            double x = pageFormat.getImageableX();  //返回与此 PageFormat相关的 Paper对象的可成像区域左上方点的 x坐标。
            double y = pageFormat.getImageableY();  //返回与此 PageFormat相关的 Paper对象的可成像区域左上方点的 y坐标。

            //Font.PLAIN： 普通样式常量  Font.ITALIC 斜体样式常量 Font.BOLD 粗体样式常量。
            TmParameters tmParameters = printSettings.getTmParameters();
            String titleFontName = tmParameters.getTitleFontName();
            Integer titleSize = tmParameters.getTitleSize();
            Font firstFont = new Font(titleFontName,Font.BOLD,titleSize);
            g2.setFont(firstFont);
            String companyName = tmParameters.getCompanyName();
            String startPhone = printVo.getStartAddressPhone();
            g2.drawString(companyName+" 咨询电话:"+startPhone,(float) x , (float) y);

            //第二行为目的地
            Integer addressSize = tmParameters.getAddressSize();
            Font secondFont = new Font(titleFontName,Font.BOLD,addressSize);
            g2.setFont(secondFont);
            String realEndAddress = printVo.getRealEndAddress();
            String endAddress = printVo.getEndAddress();
            String consigneeName = printVo.getConsigneeName();
            if(Helper.isNotEmpty(realEndAddress)){
                endAddress = realEndAddress;
            }
            String selfNo = printVo.getSelfNo();
            if(Helper.isEmpty(selfNo)){
                String selfCode = printVo.getSelfCode();
                g2.drawString(endAddress+selfCode+consigneeName,(float) x , (float) y+25);
            }else {
                g2.drawString(endAddress+selfNo+consigneeName,(float) x , (float) y+25);
            }
            //第三行，条形码
            String orderCode = printVo.getOrderCode();
            String path = tmParameters.getPath();
            BarcodeUtil.generateFile(orderCode,path);

            //把图片画到上
            try {
                File file=new File(path);
                if(!file.exists()){
                    file.mkdir();
                }
                BufferedImage image = ImageIO.read(file);
                Integer x0 = tmParameters.getX();
                Integer y0 = tmParameters.getY();
                Integer width = tmParameters.getWidth();
                Integer height = tmParameters.getHeight();
                g2.drawImage(image,x0,y0,width,height,null);
            } catch (IOException e) {
                logger.error("获取二维码图像异常",e);
            }
            return PAGE_EXISTS;
        }
    }

    private String checkNull(Object field){
        if(StringUtils.isEmpty(field)){
            return "";
        }else {
            return String.valueOf(field);
        }
    }



    public void doPrint(Printable printable) {
        try {
            PrintOrder myPrint = new PrintOrder();
            //Book 类提供文档的表示形式，该文档的页面可以使用不同的页面格式和页面 painter
            Book book = new Book(); //要打印的文档
            //PageFormat类描述要打印的页面大小和方向
            PageFormat pf = new PageFormat();  //初始化一个页面打印对象
            pf.setOrientation(PageFormat.PORTRAIT); //设置页面打印方向，从上往下，从左往右
            //设置打印纸页面信息。通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
            Paper paper = new Paper();
            TmParameters tmParameters = printSettings.getTmParameters();
            Integer paperWidth = tmParameters.getPaperWidth();
            Integer paperHeight = tmParameters.getPaperHeight();
            paper.setSize(paperWidth, paperHeight);

            Integer useHeight = tmParameters.getUseHeight();
            Integer useWidth = tmParameters.getUseWidth();
            Integer useX = tmParameters.getUseX();
            Integer useY = tmParameters.getUseY();
            paper.setImageableArea(useX, useY, useWidth, useHeight);
            pf.setPaper(paper);
            book.append(printable, pf, this.totalPageCount);
            PrinterJob job = PrinterJob.getPrinterJob();   //获取打印服务对象
            // 构建打印请求属性集
             HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
            // 设置打印格式，因为未确定类型，所以选择autosense
            DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
            // 查找所有的可用的打印服务
            PrintService printServices[] = PrintServiceLookup.lookupPrintServices(flavor, pras);
            PrintService myPrinter = null;
            if(Helper.isNotEmpty(printServices)){
                for (PrintService service : printServices) {
                    String choosePrint = printSettings.getTmParameters().getTmPrintName();
                    String name = service.getName();
                    String serviceName = checkNull(name);
                    if(serviceName.contains(choosePrint)){
                        myPrinter = service;
                        break;
                    }
                }
            }
            if(Helper.isEmpty(myPrinter)){
                logger.error("没有服务");
                throw new Exception("没有找到打印服务");
            }
            //可以输出打印机的各项属性
            job.setPrintService(myPrinter);
            job.setPageable(book);  //设置打印类
            job.print();
        } catch (Exception e) {
            logger.error("打印运单异常",e);
        }
    }
}
